
#include "StdAfx.h"
#include "Timer.h"
#include <process.h>

#define WM_CALLTIMERPROC		(WM_APP+1)

UINT CTimer::m_uTimerIDSeed = 1;
CWnd CTimer::m_TimerWnd;
CTimer::CTimerMap CTimer::m_TimerMap;

CTimer::CTimer(void)
: m_nTimerID(m_uTimerIDSeed++)
, m_pTimerProc(NULL)
, m_pUserData(NULL)
{
}

CTimer::~CTimer(void)
{
	if(IsWindow(m_TimerWnd.m_hWnd))
		CloseTimer();
}

BOOL CTimer::StartService()
{
	if(IsWindow(m_TimerWnd.m_hWnd))
		return TRUE;

	if(!m_TimerWnd.CreateEx(0, AfxRegisterWndClass(0), _T("_TimerWnd_"), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL))
		return FALSE;

	return TRUE;
}

void CTimer::StopService()
{
	if(IsWindow(m_TimerWnd.m_hWnd))
	{
		m_TimerWnd.DestroyWindow();
	}
}

void CTimer::TimerServiceProc(HWND hWnd, UINT uMsg, UINT uIDEvent, DWORD dwTime)
{
	CTimerMap::iterator it = m_TimerMap.find(uIDEvent);

	if(it != m_TimerMap.end())
	{
		CTimer* pTimer = it->second;
		if(pTimer->m_pTimerProc)
		{
			pTimer->m_pTimerProc(uIDEvent, pTimer->m_pUserData);
		}
	}
}

BOOL CTimer::StartTimer(UINT uElapse)
{
	if(m_pTimerProc == NULL)
		return FALSE;

	m_TimerMap[m_nTimerID] = this;

	return static_cast<BOOL>(m_TimerWnd.SetTimer(m_nTimerID, uElapse, TimerServiceProc));
}

BOOL CTimer::CloseTimer()
{
	CTimerMap::iterator it = m_TimerMap.find(m_nTimerID);

	if(it != m_TimerMap.end())
	{
		m_TimerMap.erase(it);
		return m_TimerWnd.KillTimer(m_nTimerID);
	}
	else
	{
		return FALSE;
	}
}